QT入门(十五) 您所在的位置:网站首页 客户端 服务端 数据库 QT入门(十五)

QT入门(十五)

2024-06-09 18:17| 来源: 网络整理| 查看: 265

TCP双向通信 效果图一 .pro文件三 .cpp中服务端的内容1.启动服务器2.服务器现有新的连接时关于 **ssocket=sserver.nextPendingConnection();** 3.服务器发现有数据进来时,要去读取数据4.服务端发送数据给客户端 四 .cpp中客户端的内容1.客户端连接服务器2.客户端向服务器发送内容3.客户端接收内容 小结

效果图

在这里插入图片描述

一 .pro文件

添加network

QT += core gui network

二 .h头文件中的定义

private slots: void on_pushButton_clicked(); void on_pushButton_4_clicked(); void on_pushButton_5_clicked(); //客户端读取发送端发来的数据的槽函数 void cread_data(); void on_pushButton_2_clicked(); //客户端点击 连接服务器,连接上会触发服务器发出newConnection的信号,进入receive_clien函数中 void receive_client(); //服务器读取客户端发来的数据的槽函数 void sread_data(); void on_pushButton_3_clicked(); void on_pushButton_6_clicked(); private: Ui::MainWindow *ui; //客户端的套接字 QTcpSocket csocket; //声明一个QTcpserver的对象,用于监听 QTcpServer sserver; //创建服务器的套接字,用于与客户端进行通信 QTcpSocket *ssocket;

QTcpSocket *ssocket;服务器的套接字,用于与客户端进行通信。由于这个套接字是在服务器的receive-client这个槽函数中函数中获取的,又要在服务端的发送函数中使用,所以要变成全局变量。

三 .cpp中服务端的内容 1.启动服务器

服务端点击启动服务器,服务器就开始监听

//启动服务器 void MainWindow::on_pushButton_2_clicked() { //监听----------启动服务器 //QHostAddress::Any 地址,接纳所有的地址 //端口号 ui->sportEdit->text()获得输入的字符串,转换成无符号短整型 sserver.listen(QHostAddress::Any,ui->sportEdit->text().toUShort()); } 2.服务器现有新的连接时

当服务器发现有人要来连接时,就会发出newconnection 的信号,从而触发槽函数receive_client(自行编写的槽函数) 在MainWindow::MainWindow(QWidget *parent) :里面添加connect关联函数

//客户端点击 连接服务器,连接上会触发服务器发出newConnection的信号,server进入new_client函数中 //动作的发出者&sserver 服务器,发出的信号是newConnection //&QTcpServer中的这个函数newConnection会发出一个信号 动作的发出者是mserver服务器 connect(&sserver,&QTcpServer::newConnection,this,&MainWindow::receive_client);

receive_client(自行编写的槽函数)

//建立接收客户端连接的槽函数,有人连接就触发这个槽函数 void MainWindow::receive_client() { //获取这个服务器sserver与客户端通信的套接字 ssocket=sserver.nextPendingConnection(); //拿到套接字后,服务器可利用ssocket这个套接字中的write(),间接的向客户端发送数据, ssocket->write("connect"); //客户端如有写入,就会触发readyread这个信号 //关联一下客户端的写入信号,本来就是指针,不用取地址 //写在这里是确保客户端连接了服务器 //信号的发出者是ssocket 服务器与客户端之间通信的套接字 //当有东西写入的时候,就会发出readyread的信号 connect(ssocket,&QTcpSocket::readyRead,this,&MainWindow::sread_data); } 关于 ssocket=sserver.nextPendingConnection();

想了很久,参考了其他的博客在这里插入图片描述 我是这么理解的 在sserver这个服务器的进程汇总,调用nextPendingConnection()这个函数,获得了一个QtcpSocket类型的指针,就是服务端的套接字,用来和客户端通信的,所以在后面的内容中,直接向ssocket里面写入内容,客户端就可以收到。但是返回的这个QtcpSocket类型的指针不可以用于另一个线程。

在接收到新客户的这个函数中,再定义一个connect,是确保客户端连接了服务器,信号的发出者是ssocket,发出的信号是准备读readyRead,触发服务器去执行sread_data这个槽函数。

3.服务器发现有数据进来时,要去读取数据 //槽函数 //服务器读取客户端csocket发来的数据的槽函数,然后显示在服务器端的stextBrowser中 void MainWindow::sread_data() { // //获得信号的发送者的套接字 // //sender()用于服务器获取客户端在发送内容的时候的套接字,其实获取到的内容就是sscoket // //dynamic_cast 将sender获得的内容强制转换成QTcpSocket* // QTcpSocket *msocket = dynamic_cast(sender()); // //读取数据 // QString msg = msocket->readAll(); // //还可以读取对方的ip // QString ip = msocket->peerAddress().toString(); // //去掉前面的#ffff // ip.remove("::ffff:"); QString msg = ssocket->readAll(); QString ip = ssocket->peerAddress().toString(); //调用文本浏览框,显示内容 ui->stextBrowser->append(ip+":"+msg); }

服务器读取客户发来的信息的时候,也是要先获取发送者的套接字QTcpSocket *msocket = dynamic_cast(sender());赋值给msock,这个临时创建的套接字,然后从这个临时创建的套接字中读取信息,还可以读取ip

sender()函数,返回的是信号来源的对象,返回的就是,是谁进入了发出的信号,进入的这个槽函数。

4.服务端发送数据给客户端 //服务器端的 发送按钮 向客户端csocket写入数据 void MainWindow::on_pushButton_3_clicked() { //获取数据 toPlainText()这个组件转字符串 QString data = ui->stextEdit->toPlainText(); ssocket->write(data.toUtf8()); }

由于ssocket是全局变量,所以上面在第三步中给它赋值了,这里就可以直接用了,直对它写入数据即可。

//服务器端的清空按钮 void MainWindow::on_pushButton_6_clicked() { //清空一下textedit ui->stextEdit->clear(); } 四 .cpp中客户端的内容 1.客户端连接服务器 //client端的连接服务器按钮 void MainWindow::on_pushButton_clicked() { // 根据输入的ip和port连接指定的服务器 csocket.connectToHost(ui->cipEdit->text(),ui->cportEdit->text().toUShort()); qDebug() //清空一下textedit ui->ctextEdit->clear(); } 3.客户端接收内容

首先在MainWindow::MainWindow(QWidget *parent) :中建立connect连接

//关联一下信号 作用是读取服务端发来的数据 //当客户端发现有数据要进来的时候,就会发出readyread这个信号,触发读取并显示数据的槽函数 connect(&csocket,&QTcpSocket::readyRead,this,&MainWindow::cread_data);

槽函数

//client端的接收服务器发来的数据的槽函数 void MainWindow::cread_data() { //通过套接字读取,保存服务器发过来的数据 QString msg = csocket.readAll(); //把数据放到文本浏览框中显示 ui->ctextBrowser->append(msg); } 小结

客户端和服务端一边一个套接字,服务器端还要加一个服务端的对象用于监听 客户端的套接字csocket(是一个变量)可以直接使用,但是服务端的套接字ssocket的赋值是在服务器对象监听到有东西来连接的时候,通过nextPendingConnection获得的,是一个指针。 服务器向客户端写东西:sscoket->write() 客户端向服务器写东西:cscoket.write()

读取服务器获得的内容ssocket->readAll(); 读取客户端获得的内容 csocket.readAll();



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有